using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace DemoAstarAlgorithm {
    // Day la Class chinh chua cac ham Khoi tao, Update, Draw Game
    public class Game1 : Microsoft.Xna.Framework.Game {
        // Khai bao cac Hang so su dung trong Game
        public static int SCREEN_WIDTH = 800;
        public static int SCREEN_HEIGHT = 600;

        //Khai bao cac bien toan cuc
        public static bool g_bPause;
        public static bool g_bEndGame;
        public static bool g_bMenusRunning;
        public static int g_iLife;
        public static int g_iSpeed;
        public static int g_iCountEnemies;
        public static Rectangle g_rPosMask;
        public static int g_iScore;
        public static int g_iEnergy;

        // Khai bao cac Bien so su dung trong Game
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        ManagerMap m_ManagerMap;
        int m_iOldMapID;
        cWitch m_Witch;
        cManagerBoom m_ManagerBoom;
        cManagerItem m_ManagerItem;
        ManagerEnemies m_ManagerEnemies;
        String m_sNameEnemies;
        cGate m_Gate;
        Texture2D m_tMask;
        cTime m_Time;
        cLetter m_Letter;
        List<cMenu> m_MenuList;
        cMenu m_MenuActive;
        cMenu m_MenuPlay;
        cMenu m_MenuEndGame;
        cMenu m_NewActiveMenu;
        KeyboardState m_LastKeybState;
        // Ham khoi tao mac dinh Game1, khoi tao Cua so Game va mot so thong tin lien quan
        public Game1() {
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = Game1.SCREEN_WIDTH;
            graphics.PreferredBackBufferHeight = Game1.SCREEN_HEIGHT;
            Content.RootDirectory = "Content";
        }

        /// <Chu thich Initialize>
        /// Ham thuc hien cac khoi tao can thiet truoc khi Game bat dau chay.
        /// Day la noi co the truy xuat den bat ky dich vu can thiet va tai len cac
        /// noi dung (ma khong phai Do hoa). Goi base.Initialize() de thong qua cac
        /// thanh phan va khoi tao chung.
        /// </Chu thich Initialize>
        protected override void Initialize() {
            Window.Title = "DemoAstarAlgorithm";
            m_LastKeybState = Keyboard.GetState();
            m_MenuList = new List<cMenu>();
            g_bPause = true;
            g_bEndGame = false;
            g_bMenusRunning = true;
            g_iLife = 3;
            g_iSpeed = 1;
            g_iScore = 0;
            g_iEnergy = 2;
            base.Initialize();
        }

        /// <Chu thich LoadContent>
        /// Ham LoadContent se duoc goi mot lan va la noi de khoi tao
        /// noi dung Game nhu Hinh anh, Am thanh,...
        /// </Chu thich LoadContent>
        protected override void LoadContent() {
            // Tao mot SpriteBatch la cong cu dung de ve hinh anh
            spriteBatch = new SpriteBatch(GraphicsDevice);
            m_ManagerMap = new ManagerMap(Content);
            m_iOldMapID = 1;
            m_ManagerBoom = new cManagerBoom(Content);
            m_ManagerItem = new cManagerItem(Content);
            m_Gate = new cGate(Content);
            m_ManagerEnemies = new ManagerEnemies();
            if (m_ManagerMap.map.IDmap == 1) {
                g_iCountEnemies = 5;
                m_ManagerBoom.m_tBoom = Content.Load<Texture2D>(@"images/boom-motmat");
                m_Witch = new cWitch(new Vector2(200, 10), Content);
                m_sNameEnemies = "bugnhot";
            }
            m_Letter = new cLetter(Content, new Vector2(0, 0));
            m_Time = new cTime(Content);
            m_tMask = Content.Load<Texture2D>(@"images/mask");
            cMenu menuMain = new cMenu("Main Menu", Content, this.GraphicsDevice);
            cMenu menuNewGame = new cMenu("Start a New Game", Content, this.GraphicsDevice);
            cMenu menuInstruction = new cMenu("Instruction", Content, this.GraphicsDevice);
            cMenu menuCredits = new cMenu("Credits", Content, this.GraphicsDevice);
            m_MenuEndGame = new cMenu("EndGame", Content, this.GraphicsDevice);
            m_MenuPlay = new cMenu(null, Content, this.GraphicsDevice);
            m_MenuList.Add(menuMain);
            m_MenuList.Add(menuNewGame);
            m_MenuList.Add(menuInstruction);
            m_MenuList.Add(menuCredits);
            m_MenuList.Add(m_MenuEndGame);
            menuMain.AddMenuItem("New Game", menuNewGame);
            menuMain.AddMenuItem("Instruction", menuInstruction);
            menuMain.AddMenuItem("Credits", menuCredits);
            menuMain.AddMenuItem("Exit Game", null);
            menuNewGame.AddMenuItem("Play Map 1", m_MenuPlay);
            menuNewGame.AddMenuItem("Play Map 2", m_MenuPlay);
            menuNewGame.AddMenuItem("Back to Main menu", menuMain);
            menuInstruction.AddMenuItem("Back to Main menu", menuMain);
            menuCredits.AddMenuItem("Back to Main menu", menuMain);
            m_MenuEndGame.AddMenuItem("Play Again", menuNewGame);
            m_MenuEndGame.AddMenuItem("Exit", null);
            m_MenuActive = menuMain;
            menuMain.WakeUp();
        }

        /// <Chu thich UnLoadContent>
        /// Ham UnloadContent se duoc goi mot lan va 
        /// la noi de huy noi dung Game
        /// </Chu thich UnLoadContent>
        protected override void UnloadContent() {
            // TODO: Unload any non ContentManager content here
        }

        private void MenuInput(KeyboardState currentKeyState) {
            m_NewActiveMenu = m_MenuActive.ProcessInput(m_LastKeybState, currentKeyState, ref m_ManagerMap);
            if ((m_ManagerMap.map.IDmap == 3) || (m_ManagerMap.m_iIDStatus == 3) && g_bPause && g_bEndGame) {
                m_NewActiveMenu = m_MenuEndGame;
            }
            if (m_NewActiveMenu == m_MenuPlay) {
                g_bMenusRunning = false;
            }
            if (m_NewActiveMenu == null)
                this.Exit();
            else if (m_NewActiveMenu != m_MenuActive)
                m_NewActiveMenu.WakeUp();
            m_MenuActive = m_NewActiveMenu;
        }

        protected void Khoitaomap() {
            if (m_iOldMapID != m_ManagerMap.map.IDmap) {
                g_iEnergy = 2;
                g_iSpeed = 1;
                m_ManagerBoom = new cManagerBoom(Content);
                m_ManagerItem = new cManagerItem(Content);
                m_ManagerEnemies = new ManagerEnemies();
                if (g_bEndGame) {
                    g_bEndGame = false;
                    m_ManagerMap = new ManagerMap(Content);
                    g_iLife = 3;
                }
                m_Time = new cTime(Content);
                if (m_ManagerMap.map.IDmap == 1) {
                    m_ManagerBoom.m_tBoom = Content.Load<Texture2D>(@"images/boom-motmat");
                    m_Witch = new cWitch(new Vector2(200, 10), Content);
                    g_iCountEnemies = 5;
                    m_sNameEnemies = "bugnhot";
                } else
                    if (m_ManagerMap.map.IDmap == 2) {
                        m_ManagerBoom.m_tBoom = Content.Load<Texture2D>(@"images/boom-ranri");
                        m_Witch = new cWitch(new Vector2(290, 270), Content);
                        g_iCountEnemies = 5;
                        m_sNameEnemies = "bugkiem";
                    } else {
                        m_Witch = new cWitch(new Vector2(290, 270), Content);
                        g_rPosMask = new Rectangle(580 - (int)m_Witch.m_v2Position.X, 490 - (int)m_Witch.m_v2Position.Y, 600, 522);
                        m_ManagerBoom = new cManagerBoom(Content);
                        m_ManagerBoom.m_tBoom = Content.Load<Texture2D>(@"images/boom-ranri");
                        g_iCountEnemies = 10;
                        m_sNameEnemies = "bugbird";
                    }
                m_iOldMapID = m_ManagerMap.map.IDmap;
            }
        }

        /// <Chu thich Update>
        /// Xu ly cac van de trong Game nhu: Cap nhat the gioi Game,
        /// kiem tr va cham, nhan ban phim, phat am thanh,...
        /// </Chu thich Update>
        protected override void Update(GameTime gameTime) {

            // TODO: Add your update logic here
            Khoitaomap();
            KeyboardState keyState = Keyboard.GetState();
            if (m_LastKeybState.IsKeyUp(Keys.P) && keyState.IsKeyDown(Keys.P) && m_Time.m_iMinute < 3 && m_ManagerMap.m_iIDStatus == 2) {
                if (g_bPause)
                    g_bPause = false;
                else
                    g_bPause = true;
            }
            if (g_bMenusRunning) {
                foreach (cMenu currentMenu in m_MenuList)
                    currentMenu.Update(gameTime.ElapsedGameTime.TotalMilliseconds, gameTime, keyState);
                MenuInput(keyState);
            } else {
                if (!g_bPause) {
                    m_Witch.Update(gameTime, keyState, m_ManagerMap.map.m_aMatrix, m_ManagerMap.map.IDmap - 1, m_ManagerEnemies);
                    m_ManagerBoom.Update(gameTime, keyState, Content, Chuan(m_Witch.m_v2Position + new Vector2(5, 30)), m_ManagerMap.map.m_aMatrix, m_ManagerMap.map.IDmap - 1);
                    m_ManagerItem.Update(gameTime, m_Witch, m_ManagerMap.map.m_aMatrix, m_ManagerMap.map.IDmap - 1, m_ManagerBoom);
                    if (g_iCountEnemies <= 0) {
                        Game1.g_bPause = true;
                        m_ManagerMap.m_iIDStatus = 0;
                        m_ManagerMap.m_iIDStatus = 4;
                    }

                    m_ManagerEnemies.Update(gameTime, Content, m_sNameEnemies, m_ManagerMap.getMapMatrix(), m_ManagerMap.map.IDmap - 1, Chuan(m_Witch.m_v2Position + new Vector2(5, 30))); ;
                    m_Gate.Update(gameTime, g_bPause);
                }
            }
            m_LastKeybState = keyState;
            base.Update(gameTime);
        }

        /// <Chu thich Draw>
        /// Ham Draw duoc goi khi Game can ve hinh anh ra man hinh
        /// </Chu thich Draw>
        protected override void Draw(GameTime gameTime) {
            GraphicsDevice.Clear(Color.Black);
            spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend);
            if (g_bMenusRunning) {
                foreach (cMenu currentMenu in m_MenuList) {
                    currentMenu.Draw(spriteBatch, Content, gameTime);
                }
                Print_Letter();
            } else {
                m_ManagerMap.Draw(spriteBatch);
                m_ManagerBoom.Draw(gameTime, Content, spriteBatch, m_ManagerMap.map.m_aMatrix, m_ManagerMap, m_ManagerItem, m_ManagerMap.map.IDmap - 1, m_ManagerEnemies, m_Witch);
                m_ManagerEnemies.Draw(spriteBatch, gameTime);
                m_Witch.Draw(spriteBatch, gameTime, ref g_bPause, m_ManagerMap);
                m_ManagerMap.Draw(spriteBatch, gameTime, m_ManagerItem);
                g_rPosMask = new Rectangle(580 - (int)m_Witch.m_v2Position.X, 490 - (int)m_Witch.m_v2Position.Y, 600, 522);
                if (m_ManagerMap.map.IDmap == 3)
                    spriteBatch.Draw(m_tMask, new Vector2(20, 40), g_rPosMask, Color.White, 0, Vector2.Zero, 1, SpriteEffects.None, 0.89f);
                m_Time.Draw(spriteBatch, gameTime, m_ManagerMap);
                m_ManagerMap.Draw(spriteBatch, gameTime, m_Time);
                m_Gate.Draw(spriteBatch);
                Print_Letter();
            }
            spriteBatch.End();
            base.Draw(gameTime);
        }

        private void Print_Letter() {
            if (m_MenuActive == m_MenuPlay) {
                m_Letter.Draw(spriteBatch, g_iEnergy.ToString(), 712, 18, 23);
                m_Letter.Draw(spriteBatch, g_iScore.ToString(), 684, 177, 23);
                m_Letter.Draw(spriteBatch, g_iLife.ToString(), 712, 225, 23);
                m_Letter.Draw(spriteBatch, g_iCountEnemies.ToString(), 712, 285, 23);
                m_Letter.Draw(spriteBatch, m_ManagerBoom.m_iNumber.ToString(), 712, 349, 23);
                m_Letter.Draw(spriteBatch, m_ManagerBoom.m_iLength.ToString(), 712, 410, 23);
                m_Letter.Draw(spriteBatch, g_iSpeed.ToString(), 712, 469, 23);
                if (m_Witch.m_iLife == 3)
                    m_Letter.Draw(spriteBatch, "1", 712, 530, 23);
                else
                    m_Letter.Draw(spriteBatch, "0", 712, 534, 23);
            } else
                if (m_MenuActive == m_MenuEndGame)
                    m_Letter.Draw(spriteBatch, g_iScore.ToString(), 185, 275, 55);
        }

        public static Vector2 Chuan(Vector2 pos) {
            int i, j;
            i = ((int)pos.X - 15) / 40;
            j = ((int)pos.Y - 25) / 40;
            return new Vector2(i * 40 + 20, j * 40 + 40);
        }
    }
}
